/**
 * @author:albert
 */

package com.bkbw.live.battle.database;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.TreeMap;

import com.bkbw.live.battle.database.bean.BagBeanManager;
import com.bkbw.live.battle.database.bean.BallBean;
import com.bkbw.live.battle.database.bean.BuildBean;
import com.bkbw.live.battle.database.bean.ConstParamsBean;
import com.bkbw.live.battle.database.bean.EquipmentBean;
import com.bkbw.live.battle.database.bean.ItemsBean;
import com.bkbw.live.battle.database.bean.LevelExpBean;
import com.bkbw.live.battle.database.bean.RoleBean;
import com.bkbw.live.battle.database.bean.TableTemplate;
import com.bkbw.live.battle.database.bean.VipBean;
import com.bkbw.live.battle.database.bean.WeaponBean;
import com.bkbw.live.battle.database.bean.WeaponHotBean;
import com.bkbw.live.battle.database.bean.WeaponsBean;
import com.bkbw.live.battle.net.client.DatabaseClient;
import com.bkbw.live.common.GameConfig;
import com.bkbw.live.common.dataproto.BattleToDatabasePb.BS2DBBuyItemReq;
import com.bkbw.live.common.dataproto.BattleToDatabasePb.BS2DBEquipReq;
import com.bkbw.live.common.dataproto.BattleToDatabasePb.BS2DBSaveCharacterReq;
import com.bkbw.live.common.dataproto.CommonMessagePb.BagItemChangePb;
import com.bkbw.live.common.dataproto.CommonMessagePb.HashLongInt;
import com.bkbw.live.common.dataproto.CommonMessagePb.TripleLongIntIntPb;
import com.bkbw.live.common.util.Utils;

public class DatabaseManager {
	// 所有的静态表名
	private static ArrayList<String> staticTableNames = new ArrayList<String>();
	public static ArrayList<String> getStaticTableNames() {
		return staticTableNames;
	}
	
	
	// 根据表名获得对应bean class的类型
	private static HashMap<String, Class> tableToBean = new HashMap<String, Class>();
	// 获取某个表的主键
	private static HashMap<String, String> tableKey = new HashMap<String, String>();
	// 根据bean class获取表
	private static HashMap<Class, String> beanToTable = new HashMap<Class, String>();
	
	static {
		System.out.println("static init 1");
	}
	
	
	private HashMap<String, Integer> inittableMap = new HashMap<String, Integer>();
	
	public void setInitTable(String table, boolean b) {
		int index = inittableMap.get(table);
		inittable[index] = b;
		if (table.equals(staticConstParamsTable)) {
			TableTemplate<String, ConstParamsBean> t = getConstParamsTable();
			ConstParam.BlockLevelPar = Integer.parseInt(t.getBeanByKey("BlockLevelPar").getParam1());
			ConstParam.EvadeLevelPar = Integer.parseInt(t.getBeanByKey("EvadeLevelPar").getParam1());
			ConstParam.FarEvadeLevelPar = Integer.parseInt(t.getBeanByKey("FarEvadeLevelPar").getParam1());
			ConstParam.HitLevelPar = Integer.parseInt(t.getBeanByKey("HitLevelPar").getParam1());
			ConstParam.GeneralPar = Integer.parseInt(t.getBeanByKey("GeneralPar").getParam1());
			GameConfig.Percentage = 1f / ConstParam.GeneralPar;
			System.out.println("GameConfig.Percentage" + GameConfig.Percentage);
		}
		System.out.println("table load " + table);
		if (isInittableAllInit()) {
			TreeMap<Integer, ItemsBean> itemsBeanTreeMap = getItemsTable().getTable(); 
			TreeMap<Integer, EquipmentBean> equipmentBeanTreeMap = getEquipmentTable().getTable();
			TreeMap<Integer, WeaponsBean> weaponsBeanTreeMap = getWeaponsTable().getTable();
			BagBeanManager.getInstance().init(itemsBeanTreeMap, equipmentBeanTreeMap, weaponsBeanTreeMap);
			System.out.println("---itemsBeanTreeMap size "+itemsBeanTreeMap.size());
			System.out.println("---equipmentBeanTreeMap size "+equipmentBeanTreeMap.size());
			System.out.println("---weaponsBeanTreeMap size "+weaponsBeanTreeMap.size());
			System.out.println("---bagbeanmanager size "+BagBeanManager.getInstance().getMap().size());
			
			//BagBeanManager.getInstance().dump();
			isTableInit = true;
		}
	}
	public boolean isInittableAllInit() {
		for (int i = 0; i < inittable.length; ++i){
			if (!inittable[i]){
				return false;
			}
		}
		return true;
	}
	
	public void resetInittable() {
		for (int i = 0; i < inittable.length; ++i){
			inittable[i] = false;
		}
	}
	
	
	// 子弹静态表
	public static final String staticBallTable = "mq_ball";
	// 角色等级
	public static final String staticLevelExpTable = "mq_levelexp";
	// 角色表，包括主角和怪物
	public static final String staticRoleTable = "mq_role";
	// vip等级
	public static final String staticVipTable = "mq_vip";
	// 冷武器
	//public static final String staticWeaponTable = "mq_weapon";
	//
	//public static final String staticWeaponHotTable = "mq_weapon_hot";
	
	public static final String staticBuildTable = "mq_build";
	
	public static final String staticWeaponsTable = "mq_weapons";
	
	public static final String staticItemsTable = "mq_items";
	
	public static final String staticEquipmentTable = "mq_equipment";
	
	public static final String staticConstParamsTable = "const_params";
	
	static {
		System.out.println("static init");
		staticTableNames.add(staticBallTable);
		staticTableNames.add(staticLevelExpTable);
		staticTableNames.add(staticRoleTable);
		staticTableNames.add(staticVipTable);
		//staticTableNames.add(staticBallTable);
		//staticTableNames.add(staticWeaponTable);
		//staticTableNames.add(staticWeaponHotTable);
		staticTableNames.add(staticBuildTable);
		staticTableNames.add(staticWeaponsTable);
		staticTableNames.add(staticItemsTable);
		staticTableNames.add(staticEquipmentTable);
		staticTableNames.add(staticConstParamsTable);
		
		
		
		tableToBean.put(staticBallTable, BallBean.class);
		tableToBean.put(staticLevelExpTable, LevelExpBean.class);
		tableToBean.put(staticRoleTable, RoleBean.class);
		tableToBean.put(staticVipTable, VipBean.class);
		//tableToBean.put(staticWeaponTable, WeaponBean.class);
		//tableToBean.put(staticWeaponHotTable, WeaponHotBean.class);
		tableToBean.put(staticBuildTable, BuildBean.class);
		tableToBean.put(staticWeaponsTable, WeaponsBean.class);
		tableToBean.put(staticItemsTable, ItemsBean.class);
		tableToBean.put(staticEquipmentTable, EquipmentBean.class);
		tableToBean.put(staticConstParamsTable, ConstParamsBean.class);
		
//		beanToTable.put(BallBean.class, staticBallTable);
//		beanToTable.put(LevelExpBean.class, staticLevelExpTable);
//		beanToTable.put(RoleBean.class, staticRoleTable);
//		beanToTable.put(VipBean.class, staticVipTable);
//		beanToTable.put(WeaponBean.class, staticWeaponTable);
//		beanToTable.put(WeaponHotBean.class, staticWeaponHotTable);
//		beanToTable.put(BuildBean.class, staticBuildTable);
//		beanToTable.put(WeaponsBean.class, staticWeaponsTable);
		for (String key : tableToBean.keySet()) {
			beanToTable.put(tableToBean.get(key), key);
		}
		
		tableKey.put(staticBallTable, "Id");
		tableKey.put(staticLevelExpTable, "Level");
		tableKey.put(staticRoleTable, "Id");
		tableKey.put(staticVipTable, "VipLevel");
		//tableKey.put(staticWeaponTable, "Id");
		//tableKey.put(staticWeaponHotTable, "Id");
		tableKey.put(staticBuildTable, "Id");
		tableKey.put(staticWeaponsTable, "Id");
		tableKey.put(staticItemsTable, "Id");
		tableKey.put(staticEquipmentTable, "Id");
		tableKey.put(staticConstParamsTable, "Key");
		
	}
	
	// 根据表名获取对应的bean class
	public static Class getBeanByTable(String tableName){
		if (tableToBean.containsKey(tableName)) {
			return tableToBean.get(tableName);
		}
		return null;
	}
	
	// 根据bean class获取对应的表名
	public static String getTableByBean(Class cls) {
		if (beanToTable.containsKey(cls)){
			return beanToTable.get(cls);
		}
		return null;
	}
	
	// 获取某个表的主键名
	public static String getKeyByTable(String tableName){
		if (tableKey.containsKey(tableName)) {
			return tableKey.get(tableName);
		}
		return null;
	}
	
	private boolean[] inittable = new boolean[staticTableNames.size()];
	
	private static DatabaseManager instance = new DatabaseManager();
	public static DatabaseManager getInstance() {
		return instance;
	}

	// ---------- none static members --------------
	
	DatabaseClient client;
	
	private boolean isTableInit = false;
	
	public boolean isTableInit() {
		return isTableInit;
	}

	private LinkedList<String> initTables = new LinkedList<String>(); 
	
	private DatabaseManager() {
		client = new DatabaseClient("127.0.0.1", 8889);
		//client.connect();
		//client = DatabaseClient.getInstance();
		
		int index = 0;
		for (String string : staticTableNames) {
			inittableMap.put(string, index);
			++index;
		}
	}
	
	public void connect() {
		client.connect();
	}
	
	public void disconnect() {
		client.disconnect();
	}
	
	public DatabaseClient getDatabaseClient() {
		return client;
	}
	
	
	TableTemplate<Integer, BallBean> ballTable;
	TableTemplate<Integer, LevelExpBean> levelExpTable;
	TableTemplate<Integer, RoleBean> roleTable;
	TableTemplate<Integer, VipBean> vipTable;
	TableTemplate<Integer, WeaponBean> weaponTable;
	TableTemplate<Integer, WeaponHotBean> weaponHotTable;
	TableTemplate<Integer, BuildBean> buildTable;
	TableTemplate<Integer, WeaponsBean> weaponsTable;
	TableTemplate<Integer, ItemsBean> itemsTable;
	TableTemplate<Integer, EquipmentBean> equipmentTable;
	TableTemplate<String, ConstParamsBean> constParamsTable;
	
	public void setTable(TableTemplate table){
		System.out.println("settable "+table.getClazz());
		//if (initTables.contains(table.getClazz())) {
		//	return;
		//}
		//initTables.add(getTableByBean(table.getClazz()));
		
		if (table.getClazz() == BallBean.class) {
			if (getBallTable() == null) {
				setBallTable(table);
			}
			else {
				getBallTable().merge(table);
			}
		}
		else if (table.getClazz() == LevelExpBean.class) {
			if (getLevelExpTable() == null) {
				setLevelExpTable(table);
			}
			else {
				getLevelExpTable().merge(table);
			}
		}
		else if (table.getClazz() == RoleBean.class) {
			if (getRoleTable() == null) {
				setRoleTable(table);
			}
			else {
				getRoleTable().merge(table);
			}
		}
		else if (table.getClazz() == VipBean.class) {
			if (getVipTable() == null) {
				setVipTable(table);
			}
			else {
				getVipTable().merge(table);
			}
		}
		else if (table.getClazz() == BuildBean.class) {
			if (getBuildTable() == null) {
				setBuildTable(table);
			}
			else {
				getBuildTable().merge(table);
			}
		}
		else if (table.getClazz() == WeaponsBean.class) {
			if (getWeaponsTable() == null) {
				setWeaponsTable(table);
			}
			else {
				getWeaponsTable().merge(table);
			}
			//System.out.println("---");
			//for (WeaponsBean weaponsBean : getWeaponsTable().getTable().values()) {
			//	Utils.dumpObject(weaponsBean);
			//}
		}
		else if (table.getClazz() == ItemsBean.class) {
			if (getItemsTable() == null) {
				setItemsTable(table);
			}
			else {
				getItemsTable().merge(table);
			}
			//System.out.println("---");
			//for (ItemsBean weaponsBean : getItemsTable().getTable().values()) {
			//	Utils.dumpObject(weaponsBean);
			//}
		}
		else if (table.getClazz() == EquipmentBean.class) {
			if (getEquipmentTable() == null) {
				setEquipmentTable(table);
			}
			else {
				getEquipmentTable().merge(table);
			}
			//System.out.println("---");
			//for (EquipmentBean weaponsBean : getEquipmentTable().getTable().values()) {
			//	Utils.dumpObject(weaponsBean);
			//}
		}
		else if (table.getClazz() == ConstParamsBean.class) {
			if (getConstParamsTable() == null) {
				setConstParamsTable(table);
			}
			else {
				getConstParamsTable().merge(table);
			}
			
		}
		//if (initTables.size() == staticTableNames.size()) {
		
	}

	public TableTemplate<Integer, BallBean> getBallTable() {
		return ballTable;
	}

	public void setBallTable(TableTemplate<Integer, BallBean> ballTable) {
		this.ballTable = ballTable;
	}

	public TableTemplate<Integer, LevelExpBean> getLevelExpTable() {
		return levelExpTable;
	}

	public void setLevelExpTable(TableTemplate<Integer, LevelExpBean> levelExpTable) {
		this.levelExpTable = levelExpTable;
	}

	public TableTemplate<Integer, RoleBean> getRoleTable() {
		return roleTable;
	}

	public void setRoleTable(TableTemplate<Integer, RoleBean> roleTable) {
		this.roleTable = roleTable;
	}

	public TableTemplate<Integer, VipBean> getVipTable() {
		return vipTable;
	}

	public void setVipTable(TableTemplate<Integer, VipBean> vipTable) {
		this.vipTable = vipTable;
	}
	
	public TableTemplate<Integer, WeaponBean> getWeaponTable() {
		return weaponTable;
	}
	
	public void setWeaponTable(TableTemplate<Integer, WeaponBean> weaponTable){
		this.weaponTable = weaponTable;
	}

	public TableTemplate<Integer, WeaponHotBean> getWeaponHotTable() {
		return weaponHotTable;
	}

	public void setWeaponHotTable(TableTemplate<Integer, WeaponHotBean> weaponHotTable) {
		this.weaponHotTable = weaponHotTable;
	}

	public TableTemplate<Integer, BuildBean> getBuildTable() {
		return buildTable;
	}
	
	public void setBuildTable(TableTemplate<Integer, BuildBean> buildTable){
		this.buildTable = buildTable;
	}

	public TableTemplate<Integer, WeaponsBean> getWeaponsTable() {
		return weaponsTable;
	}

	public void setWeaponsTable(TableTemplate<Integer, WeaponsBean> weaponsTable) {
		this.weaponsTable = weaponsTable;
	}
	
	public TableTemplate<Integer, ItemsBean> getItemsTable() {
		return itemsTable;
	}

	public void setItemsTable(TableTemplate<Integer, ItemsBean> itemsTable) {
		this.itemsTable = itemsTable;
	}
	
	public TableTemplate<Integer, EquipmentBean> getEquipmentTable() {
		return equipmentTable;
	}

	public void setEquipmentTable(TableTemplate<Integer, EquipmentBean> equipmentTable) {
		this.equipmentTable = equipmentTable;
	}
	
	public TableTemplate<String, ConstParamsBean> getConstParamsTable() {
		return constParamsTable;
	}

	public void setConstParamsTable(TableTemplate<String, ConstParamsBean> constParamsTable) {
		this.constParamsTable = constParamsTable;
	}
	
	// ------------------- db request -------------------
	public void sendDbCharacterReq(int tableId, int characterId, int sessionId) 
	{
		this.client.sendDbCharacterReq(tableId, characterId, sessionId);
		
	}
	
	public void sendDbBagItemDetailReq(int tableId, int charId, int sessionId,  long uid) 
	{
		this.client.sendDbBagItemDetailReq(tableId, charId, sessionId, uid);
		
	}
	
	public void sendDbDropBagItemReq(int tableId, int charId, int sessionId, List<BagItemChangePb> dropItems) 
	{
		this.client.sendDbDropBagItemReq(tableId, charId, sessionId, dropItems);
		
	}
	
	public void sendDbUseBagItemReq(int tableId, int charId, int sessionId, List<BagItemChangePb> useItems) 
	{
		this.client.sendDbUseBagItemReq(tableId, charId, sessionId, useItems);
	}
	
	public void sendDbSaveCharacterReq(BS2DBSaveCharacterReq req) {
		this.client.sendDbSaveCharacterReq(req);
	}
	
	public void sendDbEquipReq(BS2DBEquipReq req) {
		this.client.sendDbEquipReq(req);
	}
	
	public void sendDbBuyItemReq(BS2DBBuyItemReq req) {
		this.client.sendDbBuyItemReq(req);
	}

}
